package fr.lelouet.ServersModel.virtual;

import java.util.Set;

import fr.lelouet.ServersModel.physical.PhysicalServer;
import fr.lelouet.ServersModel.physical.Rack;

/**
 * A VirtualServer is a virtual machine that contains virtual machines.<br />
 * It is contained within a rack of servers<br />
 * Its values of CPUs are deduced from the park of servers, to have every server
 * on the same scale: basically, a 1GHz quadri-core will contains 4 CPUs if
 * every server has (at least twice) its frequency.<br />
 * We assume that a server takes a very short time to boot and wake up.
 * @author le louet
 */
public interface VirtualServer extends Set<VirtualMachine> {

  /**
   * @return the underlying server model this use, that may be null.
   */
  public PhysicalServer getModel();

  /** @return the {@link Rack} this is contained in */
  public Rack getRack();

  /** the number of virtual CPUs that can be used by the virtual machines */
  public int getMaxCPUs();

  /** the memory usable by the virtual machines */
  public int getMaxMemory();

  /** @return the power used when the server is off */
  public double getOFFConsumption();

  /**
   * @return the power consumed on use, in Watt
   * @param ncpus
   *          the number of virtual CPUs to use
   * @param nmem
   *          the number of Mo to use
   */
  public double getConsumption(int ncpus, int nmem);

  /**
   * @param mig
   *          the {@link Migration} to apply
   * @param totalCPU
   *          the total number of CPUs used by other tasks on this
   * @param totalRAMMos
   *          the total number of ram used by other tasks on this
   * @return the energy in J required to apply mig on this
   */
  public double getMigrationEnergy(Migration mig, int totalCPU, int totalRAMMos);

  /**
   * @param mig
   *          the {@link Migration} to apply
   * @param totalCPU
   *          the total number of CPUs used by all tasks on this
   * @param totalRAMMos
   *          the total number of ram used by all tasks on this
   * @return the time in s required to apply mig on this
   */
  public double getMigrationTime(Migration mig, int totalCPU, int totalRAMMos);

}
